#include <iostream>
#include "EmpiricalModeDecomposition.h"
#include <iomanip>

#define SIZE 46
using namespace std;

/*
 This code implements empirical mode decomposition in C.
 Required paramters include:
 - order: the number of IMFs to return
 - iterations: the number of iterations per IMF
 - locality: in samples, the nearest two extrema may be
 If it is not specified, there is no limit (locality = 0).

 Typical use consists of calling emdCreate(), followed by
 emdDecompose(), and then using the struct's "imfs" field
 to retrieve the data. Call emdClear() to deallocate memory
 inside the struct.
*/

void apply_emd_filter(double signal[], double imf[], int order);

void copy(double[], float[]);

int main()
{
	
	double ndvi_serie[] = {0.00000000,0.00000000,0.00000000,0.00000000,0.08042200,0.00000000,0.00000000,0.00000000,0.38239200,0.00000000,0.00000000,0.00000000,0.48894400,0.77333975,0.76516700,0.70760800,0.84384500,0.73747400,0.70174100,0.66863100,0.51041700,0.52688700,0.48981100,0.33789200,0.15948900,0.40740700,0.45838000,0.31403100,0.60755700,0.75955800,0.75318400,0.77837800,0.79945350,0.78072400,0.72502180,0.62643000,0.48121900,0.48379700,0.23127800,0.40833300,0.37275200,0.48659700,0.15922300,0.44129000,0.43309300,0.00000000};
	//{0,0,0,0,0.080422,0,0,0,0.382392,0,0,0,0.488944,0.77334,0.765167,0.707608,0.843845,0.737474,0.701741,0.668631,0.510417,0.526887,0.489811,0.337892,0.159489,0.407407,0.45838,0.314031,0.607557,0.759558,0.753184,0.778378,0.799454,0.780724,0.725022,0.62643,0.481219,0.483797,0.231278,0.408333,0.372752,0.486597,0.159223,0.44129,0.433093,0}; 
	// ndvi 2333 2251, order = 4;
	//const float ndvi_serie[] = {0,0,0,0,0.0802152,0,0,0,0.169409,0,0,0,0.431764,0.539211,0.503649,0.469633,0.581717,0.488184,0.470344,0.470309,0.438343,0.369724,0.24719,0.18187,0.187907,0.19776,0.227707,0.267311,0.42201,0.573885,0.475841,0.525739,0.580178,0.495756,0.449137,0.383041,0.298675,0.333471,0.179296,0.210828,0.213349,0.270873,0.19045,0.227824,0.245668,0}; 
	// evi	2333 2251, order = 3;
	//const float ndvi_serie[] = {0,0,0,0,-0.00464822,0.0252989,0.0439713,0.051369,0.0304009,0.0298982,0.0598163,0.106543,0.136782,0.229287,0.284666,0.326299,0.323702,0.320346,0.324909,0.317514,0.265571,0.238643,0.217409,0.222502,0.228116,0.248602,0.258754,0.273411,0.271292,0.277604,0.302426,0.333114,0.34899,0.336109,0.29491,0.248742,0.178588,0.0889943,0.0489103,0.0417413,0.0530504,0.072495,0.112888,0.0968258,0.0829218,0};
	// lswi	2333 2251, order = 3;
	double result[46];
	apply_emd_filter(ndvi_serie, result, 3);
	return 0;
}


void apply_emd_filter(double intp[], double imf[], int order)
{
	emdData emd_proc;	
		int size = SIZE;int iterations = 23;int locality = 0;
	emdCreate(&emd_proc, size, order, iterations, locality);
	float signal[SIZE];
	copy(intp, signal);
	emdDecompose(&emd_proc, signal);

	for (int o = 0; o < order; ++o)
	{
		cout << "IMF " << o << "\t";
		for (int i = 0; i < size; ++i)
		{
			imf[i] = emd_proc.imfs[o][i];
			cout << imf[i] << "\t";
		}
		cout << "\n";
	}

	emdClear(&emd_proc);
	return;
}


void copy( double src[], float dest[] )
{
	for (int i = 0; i < SIZE; ++i)
		dest[i] = (float) src[i];
	return;
}